package com.geneqiao.jdbc.sql;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class SelectSql extends Sql
{
	private List<String> selectColumns = new ArrayList<>();
	private Map<String, String> innerJoins = new HashMap<>();
	private Map<String, String> leftJoins = new HashMap<>();
	private boolean isInnerJoin = false;
	private boolean isLeftJoin = false;

	public SelectSql(String table)
	{
		this.tables.add(table);
	}

	public SelectSql(String table, String[] columns)
	{
		this.tables.add(table);
		for (String str : columns)
		{
			this.selectColumns.add(str);
		}
	}

	public SelectSql inner(String table, String key)
	{
		this.isInnerJoin = true;
		this.tables.add(table);
		this.innerJoins.put(table, key);
		return this;
	}

	public Sql left(String table, String key)
	{
		this.isLeftJoin = true;
		this.tables.add(table);
		this.leftJoins.put(table, key);
		return this;
	}

	@Override
	public String toString()
	{
		StringBuilder sb = new StringBuilder();
		sb.append("SELECT");
		if (tables.size() == 1)
			sigleTable(sb);
		else
		{
			if (isInnerJoin)
				innerJoin(sb);
			else if (isLeftJoin)
				leftJoin(sb);
			else
			{

			}
		}
		appendWhere(sb);
		return sb.toString();
	}

	private void leftJoin(StringBuilder sb)
	{
		String tableStr = "";
		for (int i = 0; i < tables.size(); i++)
		{
			if(i == 0 && selectColumns.size() > 0)
			{
				for (String col : selectColumns)
				{
					sb.append(" t0.").append(col).append(",");
				}
				sb.delete(sb.length() - 1, sb.length());
			}
			else
			{
				sb.append(" t").append(i).append(".*");
			}
			tableStr += tables.get(i) + " t" + i;
			if (i != tables.size() - 1)
			{
				sb.append(",");
				tableStr += " LEFT JOIN ";
			}
		}
		sb.append(" FROM ").append(tableStr);
		if (leftJoins.size() > 0)
		{
			sb.append(" ON ");
			Set<String> keys = leftJoins.keySet();
			for (String key : keys)
			{
				sb.append("t").append(tables.indexOf(key) - 1);
				sb.append(".").append(leftJoins.get(key)).append("=t").append(tables.indexOf(key)).append(".")
						.append(leftJoins.get(key));
			}
		}
	}

	private void innerJoin(StringBuilder sb)
	{
		String tableStr = "";
		for (int i = 0; i < tables.size(); i++)
		{
			if(i == 0 && selectColumns.size() > 0)
			{
				for (String col : selectColumns)
				{
					sb.append(" t0.").append(col).append(",");
				}
				sb.delete(sb.length() - 1, sb.length());
			}
			else
			{
				sb.append(" t").append(i).append(".*");
			}
			tableStr += tables.get(i) + " t" + i;
			if (i != tables.size() - 1)
			{
				sb.append(",");
				tableStr += ",";
			}
		}
		sb.append(" FROM ").append(tableStr);
		if (innerJoins.size() > 0)
		{
			sb.append(" WHERE");
			Set<String> keys = innerJoins.keySet();
			for (String key : keys)
			{
				sb.append(" t0.").append(innerJoins.get(key)).append("=t").append(tables.indexOf(key)).append(".")
						.append(innerJoins.get(key)).append(" AND");
			}
			sb.delete(sb.length() - 4, sb.length());
		}
	}

	private void sigleTable(StringBuilder sb)
	{
		if (selectColumns.size() > 0)
		{
			for (String col : selectColumns)
			{
				sb.append(" t0.").append(col).append(",");
			}
			sb.delete(sb.length() - 1, sb.length());
		}
		else
			sb.append(" t0.*");
		sb.append(" FROM ").append(tables.get(0)).append(" t0");
	}
}
